/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.guptarulie.jmeter.protocol.mm7.deliveryrequest.control.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collection;

import javax.swing.BorderFactory;
//import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import org.apache.jmeter.control.gui.LogicControllerGui;
import org.apache.jmeter.gui.JMeterGUIComponent;
import org.apache.jmeter.gui.UnsharedComponent;
import org.apache.jmeter.gui.util.HorizontalPanel;
import org.apache.jmeter.gui.util.MenuFactory;
import org.apache.jmeter.gui.util.VerticalPanel;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

import com.guptarulie.jmeter.protocol.mm7.deliveryrequest.control.MM7DeliveryRequestReceiverControl;

public class MM7DeliveryRequestReceiverControlGui extends LogicControllerGui
    implements JMeterGUIComponent, ActionListener, UnsharedComponent {
    /**
	 * 
	 */
	private static final long serialVersionUID = -6377622471027738730L;

	private static final Logger log = LoggingManager.getLoggerForClass();

    private JTextField portField, rcptAddrField, vaspIDField, srvcCodeField,
    					priorityField, subjectField, chargedPartyField, msgCountField,
    					successCountField;
    
    private JRadioButton dlvryReportTrueBox, dlvryReportFalseBox, readReplyReportTrueBox,
    					readReplyReportFalseBox;
    
    private JComboBox msgClassBox;
    
    private JButton stop, start, reset;
    
    private int totalMsgCount, successCount;

    private static final String ACTION_STOP = "stop"; // $NON-NLS-1$

    private static final String ACTION_START = "start"; // $NON-NLS-1
    
    private static final String ACTION_RESET = "reset"; // $NON-NLS-1
    
    private static String mm7deliveryreceivername = "MM7 Delivery Request Receiver";
    private static String RESULTS_FIELD_NAME = "MM7DeliveryRequestReceiverControlGui:msgCountField";

    private MM7DeliveryRequestReceiverControl mm7ReceiverController;

    public MM7DeliveryRequestReceiverControlGui() {
        super();
        log.debug("Creating MM7DeliveryRequestReceiverControlGui");
        init();
    }

    public TestElement createTestElement() {
        mm7ReceiverController = new MM7DeliveryRequestReceiverControl(this);
        log.info("creating/configuring model = " + mm7ReceiverController);
        modifyTestElement(mm7ReceiverController);
        return mm7ReceiverController;
    }

    /**
     * Modifies a given TestElement to mirror the data in the gui components.
     *
     * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
     */
    public void modifyTestElement(TestElement el) {
        configureTestElement(el);
        if (el instanceof MM7DeliveryRequestReceiverControl) {
        	log.info("Delivery Request Receiver: Modify Test Element Called...");
            mm7ReceiverController = (MM7DeliveryRequestReceiverControl) el;
            mm7ReceiverController.setPort(portField.getText());
            mm7ReceiverController.setVaspID(vaspIDField.getText());
            mm7ReceiverController.setChargedParty(chargedPartyField.getText());
            mm7ReceiverController.setDeliveryReport(dlvryReportTrueBox.isSelected());
            mm7ReceiverController.setReadReplyReport(readReplyReportTrueBox.isSelected());
            mm7ReceiverController.setMsgClass(msgClassBox.getSelectedIndex());
            mm7ReceiverController.setPriority(priorityField.getText());
            mm7ReceiverController.setRecipientAddress(rcptAddrField.getText());
            mm7ReceiverController.setServiceCode(srvcCodeField.getText());
            mm7ReceiverController.setSubject(subjectField.getText());
        }
    }

    public String getStaticLabel()
    {
      return mm7deliveryreceivername;
    }
    
    public void setStaticLabel(String mm7deliveryreceivername )
    {
    	MM7DeliveryRequestReceiverControlGui.mm7deliveryreceivername = mm7deliveryreceivername;
    }

    public String getLabelResource()
    {
      return mm7deliveryreceivername;
    }

    @SuppressWarnings("unchecked")
	public Collection getMenuCategories() {
        return Arrays.asList(new String[] { MenuFactory.NON_TEST_ELEMENTS });
    }

    public void configure(TestElement element) {
        log.debug("Configuring gui with " + element);
        super.configure(element);
        mm7ReceiverController = (MM7DeliveryRequestReceiverControl) element;
        portField.setText(mm7ReceiverController.getPortString());
        msgCountField.setText(Integer.toString(totalMsgCount));
        msgCountField.setText(Integer.toString(successCount));
        repaint();
    }


    public void actionPerformed(ActionEvent action) {
        String command = action.getActionCommand();

        if (command.equals(ACTION_STOP)) {
            mm7ReceiverController.stopMM7DeliveryReceiver();
            stop.setEnabled(false);
            start.setEnabled(true);
            reset.setEnabled(false);
        } else if (command.equals(ACTION_START)) {
        	successCount = 0;
        	totalMsgCount = 0;
            modifyTestElement(mm7ReceiverController);
            mm7ReceiverController.startDeliveryReceiver(this);
            start.setEnabled(false);
            stop.setEnabled(true);
            reset.setEnabled(true);
        }
        else if (command.equals(ACTION_RESET)) {
        	successCount = 0;
        	totalMsgCount = 0;
            msgCountField.setText(Integer.toString(totalMsgCount));
            msgCountField.setText(Integer.toString(successCount));
            repaint();
            start.setEnabled(false);
            stop.setEnabled(true);
            reset.setEnabled(true);
        }
    }

    private void init() {// called from ctor, so must not be overridable
        totalMsgCount = 0;
        successCount = 0;
    	setLayout(new BorderLayout(0, 5));
        setBorder(makeBorder());
        add(makeTitlePanel(), BorderLayout.NORTH);

        JPanel mainPanel = new JPanel(new BorderLayout());

        // VASP Details Panel
        VerticalPanel vaspDetailsPanel = new VerticalPanel();
        vaspDetailsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
                "VASP Details"));
        final JPanel vaspIDPanel = getVaspIDPanel();
        final JPanel portPanel = getPortPanel();
        portPanel.add(vaspIDPanel,BorderLayout.EAST);
        vaspDetailsPanel.add(portPanel);

        // MM Details Panel
        JPanel mmDetailsPanel = new VerticalPanel();
        //mmDetailsPanel.setLayout(new BorderLayout());
        mmDetailsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
                "MM Details")); // $NON-NLS-1$

        final JPanel rcptAddPanel 		= getRcptAddrSrvCodePanel();
        final JPanel priorityPanel 		= getPrioritySubjectPanel();
        final JPanel msgClassPanel		= getMsgClassChrgdPartyPanel();
        final JPanel dlvryReportPanel 	= getDeliveryReportPanel();
        final JPanel rdRplyReportPanel 	= getReadReplyReportPanel();
  
        mmDetailsPanel.add(rcptAddPanel);
        mmDetailsPanel.add(priorityPanel);
        mmDetailsPanel.add(msgClassPanel);
        mmDetailsPanel.add(dlvryReportPanel);
        mmDetailsPanel.add(rdRplyReportPanel);
        
        // Action Panel
        JPanel actionPanel = new VerticalPanel();
        //mmDetailsPanel.setLayout(new BorderLayout());
        actionPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
                "Action")); // $NON-NLS-1$
        
        actionPanel.add(getActionPanel());
        
        // Results Panel
        JPanel resultPanel = new VerticalPanel();
        resultPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
        "Results")); // $NON-NLS-1$
        resultPanel.add(getResultsPanel());
        
        JPanel actionResultPanel = new VerticalPanel();
        actionResultPanel.add(resultPanel);
        actionResultPanel.add(actionPanel);
        //resultPanel.add(actionPanel);
        
        mainPanel.add(vaspDetailsPanel, BorderLayout.NORTH);
        mainPanel.add(mmDetailsPanel, BorderLayout.CENTER);
        mainPanel.add(actionResultPanel, BorderLayout.SOUTH);
        add(mainPanel, BorderLayout.CENTER);

    }
    
    protected JPanel getResultsPanel() {
        msgCountField = new JTextField("0", 8);
        msgCountField.setName(RESULTS_FIELD_NAME);
        JLabel label = new JLabel("Total Messages Received:"); // $NON-NLS-1$
        label.setLabelFor(msgCountField);

        successCountField = new JTextField("0", 8);
        successCountField.setName(RESULTS_FIELD_NAME);
        JLabel label1 = new JLabel("Successful Messages:"); // $NON-NLS-1$
        label1.setLabelFor(successCountField);

        JPanel panel = new HorizontalPanel();
        panel.add(label);
        panel.add(msgCountField);
        panel.add(label1);
        panel.add(successCountField);
        return panel;
    }

    protected JPanel getPortPanel() {
        portField = new JTextField(MM7DeliveryRequestReceiverControl.DEFAULT_PORT_S, 8);
        portField.setName(MM7DeliveryRequestReceiverControl.PORT);

        JLabel label = new JLabel(JMeterUtils.getResString("web_server_port")); // $NON-NLS-1$
        label.setLabelFor(portField);

        JPanel panel = new JPanel(new BorderLayout(5, 0));
        panel.add(label, BorderLayout.WEST);
        panel.add(portField, BorderLayout.CENTER);

        return panel;
    }

    protected JPanel getVaspIDPanel() {
        vaspIDField = new JTextField(MM7DeliveryRequestReceiverControl.DEFAULT_VASP_ID, 20);
        vaspIDField.setName(MM7DeliveryRequestReceiverControl.VASP_ID);

        JLabel label = new JLabel("VASP ID:"); // $NON-NLS-1$
        label.setLabelFor(vaspIDField);

        JPanel panel = new JPanel(new BorderLayout(5, 0));
        panel.add(label, BorderLayout.WEST);
        panel.add(vaspIDField, BorderLayout.CENTER);
        return panel;
    }

    protected JPanel getRcptAddrSrvCodePanel() {
        rcptAddrField = new JTextField(20);
        rcptAddrField.setName(MM7DeliveryRequestReceiverControl.RCPT_ADDR);
        JLabel label = new JLabel("Recipient Address:"); // $NON-NLS-1$
        label.setLabelFor(rcptAddrField);

        srvcCodeField = new JTextField(20);
        srvcCodeField.setName(MM7DeliveryRequestReceiverControl.SRVC_CODE);
        JLabel label1 = new JLabel("Service Code:"); // $NON-NLS-1$
        label1.setLabelFor(srvcCodeField);
        
        JPanel panel = new HorizontalPanel();
        panel.add(label);
        panel.add(rcptAddrField);
        panel.add(label1);
        panel.add(srvcCodeField);
        return panel;
    }
    
    protected JPanel getPrioritySubjectPanel() {
        priorityField = new JTextField(28);
        priorityField.setName(MM7DeliveryRequestReceiverControl.PRIORITY);
        JLabel label = new JLabel("Priority:"); // $NON-NLS-1$
        label.setLabelFor(priorityField);
        
        subjectField = new JTextField(20);
        subjectField.setName(MM7DeliveryRequestReceiverControl.SUBJECT);
        JLabel label1 = new JLabel("Subject:"); // $NON-NLS-1$
        label1.setLabelFor(subjectField);
        
        JPanel panel = new HorizontalPanel();
        panel.add(label);
        panel.add(priorityField);
        panel.add(label1);
        panel.add(subjectField);
        return panel;
    }
    
    private JPanel getDeliveryReportPanel(){

        ButtonGroup group = new ButtonGroup();

        dlvryReportTrueBox = new JRadioButton("Yes"); //$NON-NLS-1$
        group.add(dlvryReportTrueBox);
        dlvryReportTrueBox.setSelected(true);

        dlvryReportFalseBox = new JRadioButton("No"); //$NON-NLS-1$
        group.add(dlvryReportFalseBox);
        
        JLabel label = new JLabel("Delivery Report Required:");
        label.setLabelFor(dlvryReportTrueBox);

        JPanel panel = new HorizontalPanel();
        panel.add(label);
        panel.add(dlvryReportTrueBox);
        panel.add(dlvryReportFalseBox);
        return panel;
    }

    private JPanel getReadReplyReportPanel(){

        ButtonGroup group = new ButtonGroup();

        readReplyReportTrueBox = new JRadioButton("Yes"); //$NON-NLS-1$
        group.add(readReplyReportTrueBox);
        readReplyReportTrueBox.setSelected(true);

        readReplyReportFalseBox = new JRadioButton("No"); //$NON-NLS-1$
        group.add(readReplyReportFalseBox);
        
        JLabel label = new JLabel("Read Reply Report Required:");
        label.setLabelFor(readReplyReportTrueBox);

        JPanel panel = new HorizontalPanel();
        panel.add(label);
        panel.add(readReplyReportTrueBox);
        panel.add(readReplyReportFalseBox);
        return panel;
    }

    private JPanel getMsgClassChrgdPartyPanel() {
        DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
        // Note: position of these elements in the menu *must* match the
        // corresponding ProxyControl.GROUPING_* values.
        comboBoxModel.addElement("Advertisement"); // $NON-NLS-1$
        comboBoxModel.addElement("Information Service"); // $NON-NLS-1$
        comboBoxModel.addElement("Accounting"); // $NON-NLS-1$
        msgClassBox = new JComboBox(comboBoxModel);
        msgClassBox.setSelectedIndex(0);
 //       msgClassBox.addItemListener(this);
        JLabel label = new JLabel("Message Class:"); // $NON-NLS-1$
        label.setLabelFor(msgClassBox);
        
        chargedPartyField = new JTextField(20);
        chargedPartyField.setName(MM7DeliveryRequestReceiverControl.CHARGED_PARTY);
        JLabel label1 = new JLabel("Charged Party:"); // $NON-NLS-1$
        label1.setLabelFor(chargedPartyField);

        HorizontalPanel panel = new HorizontalPanel();
        panel.add(label);
        panel.add(msgClassBox);
        panel.add(label1);
        panel.add(chargedPartyField);

        return panel;
    }
    
    private JPanel getActionPanel() {
        start = new JButton("start"); // $NON-NLS-1$
        start.addActionListener(this);
        start.setActionCommand(ACTION_START);
        start.setEnabled(true);

        stop = new JButton("stop"); // $NON-NLS-1$
        stop.addActionListener(this);
        stop.setActionCommand(ACTION_STOP);
        stop.setEnabled(false);

        reset = new JButton("reset"); // $NON-NLS-1$
        reset.addActionListener(this);
        reset.setActionCommand(ACTION_RESET);
        reset.setEnabled(false);
        
        JPanel panel = new JPanel();
        panel.add(start);
        panel.add(stop);
        panel.add(reset);
        return panel;
    }

    public void clearGui(){
        super.clearGui();
        portField.setText(MM7DeliveryRequestReceiverControl.DEFAULT_PORT_S);
       // counterText.setText("0");
    }
    
    synchronized public void udpateResultsPanel(Boolean isSuccessMsg) {
    	log.info("Updated from the Receiver Thread.");
    	if (isSuccessMsg)
    		successCountField.setText(Integer.toString(++successCount));
    	else
    		msgCountField.setText(Integer.toString(++totalMsgCount));
        repaint();
    }

}